/* $Id: event_set.c,v 1.1.1.1 2003/10/11 16:13:36 mucci Exp $
 * Descriptions of the events available for different processor types.
 *
 * Copyright (C) 2001-2002  Mikael Pettersson
 */
#include "event_codes.h"
#include "libperfctr.h"
#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))

/*
 * Generic events.
 */

const struct perfctr_event_set perfctr_generic_event_set = {
    PERFCTR_X86_GENERIC,
    0,
    0, 0
};

/*
 * Intel Pentium (P5) events.
 */

#define P5_EVENT(code,mask)	{ #code,code,mask,0 }

static const struct perfctr_event p5_events[] = {
    P5_EVENT(P5_DATA_READ, 0x3),
    P5_EVENT(P5_DATA_WRITE, 0x3),
    P5_EVENT(P5_DATA_TLB_MISS, 0x3),
    P5_EVENT(P5_DATA_READ_MISS, 0x3),
    P5_EVENT(P5_DATA_WRITE_MISS, 0x3),
    P5_EVENT(P5_WRITE_HIT_TO_M_OR_E_STATE_LINES, 0x3),
    P5_EVENT(P5_DATA_CACHE_LINES_WRITTEN_BACK, 0x3),
    P5_EVENT(P5_EXTERNAL_SNOOPS, 0x3),
    P5_EVENT(P5_EXTERNAL_DATA_CACHE_SNOOP_HITS, 0x3),
    P5_EVENT(P5_MEMORY_ACCESSES_IN_BOTH_PIPES, 0x3),
    P5_EVENT(P5_BANK_CONFLICTS, 0x3),
    P5_EVENT(P5_MISALIGNED_DATA_MEMORY_OR_IO_REFERENCES, 0x3),
    P5_EVENT(P5_CODE_READ, 0x3),
    P5_EVENT(P5_CODE_TLB_MISS, 0x3),
    P5_EVENT(P5_CODE_CACHE_MISS, 0x3),
    P5_EVENT(P5_ANY_SEGMENT_REGISTER_LOADED, 0x3),
    P5_EVENT(P5_BRANCHES, 0x3),
    P5_EVENT(P5_BTB_HITS, 0x3),
    P5_EVENT(P5_TAKEN_BRANCH_OR_BTB_HIT, 0x3),
    P5_EVENT(P5_PIPELINE_FLUSHES, 0x3),
    P5_EVENT(P5_INSTRUCTIONS_EXECUTED, 0x3),
    P5_EVENT(P5_INSTRUCTIONS_EXECUTED_IN_V_PIPE, 0x3),
    P5_EVENT(P5_BUS_CYCLE_DURATION, 0x3),
    P5_EVENT(P5_WRITE_BUFFER_FULL_STALL_DURATION, 0x3),
    P5_EVENT(P5_WAITING_FOR_DATA_MEMORY_READ_STALL_DURATION, 0x3),
    P5_EVENT(P5_STALL_ON_WRITE_TO_AN_E_OR_M_STATE_LINE, 0x3),
    P5_EVENT(P5_LOCKED_BUS_CYCLE, 0x3),
    P5_EVENT(P5_IO_READ_OR_WRITE_CYCLE, 0x3),
    P5_EVENT(P5_NONCACHEABLE_MEMORY_READS, 0x3),
    P5_EVENT(P5_PIPELINE_AGI_STALLS, 0x3),
    P5_EVENT(P5_FLOPS, 0x3),
    P5_EVENT(P5_BREAKPOINT_MATCH_ON_DR0_REGISTER, 0x3),
    P5_EVENT(P5_BREAKPOINT_MATCH_ON_DR1_REGISTER, 0x3),
    P5_EVENT(P5_BREAKPOINT_MATCH_ON_DR2_REGISTER, 0x3),
    P5_EVENT(P5_BREAKPOINT_MATCH_ON_DR3_REGISTER, 0x3),
    P5_EVENT(P5_HARDWARE_INTERRUPTS, 0x3),
    P5_EVENT(P5_DATA_READ_OR_WRITE, 0x3),
    P5_EVENT(P5_DATA_READ_MISS_OR_WRITE_MISS, 0x3),
};

const struct perfctr_event_set perfctr_p5_event_set = {
    PERFCTR_X86_INTEL_P5,
    0,
    ARRAY_SIZE(p5_events), p5_events
};

/*
 * Intel Pentium MMX (P5MMX) events.
 */

static const struct perfctr_event p5mmx_events[] = {
    P5_EVENT(P5MMX_BUS_OWNERSHIP_LATENCY, 0x1),
    P5_EVENT(P5MMX_BUS_OWNERSHIP_TRANSFERS, 0x2),
    P5_EVENT(P5MMX_MMX_INSTRUCTIONS_EXECUTED_U_PIPE, 0x1),
    P5_EVENT(P5MMX_MMX_INSTRUCTIONS_EXECUTED_V_PIPE, 0x2),
    P5_EVENT(P5MMX_CACHE_M_STATE_LINE_SHARING, 0x1),
    P5_EVENT(P5MMX_CACHE_LINE_SHARING, 0x2),
    P5_EVENT(P5MMX_EMMS_INSTRUCTIONS_EXECUTED, 0x1),
    P5_EVENT(P5MMX_TRANSITIONS_BETWEEN_MMX_AND_FP_INSTRUCTIONS, 0x2),
    P5_EVENT(P5MMX_BUS_UTILIZATION_DUE_TO_PROCESSOR_ACTIVITY, 0x1),
    P5_EVENT(P5MMX_WRITES_TO_NONCACHEABLE_MEMORY, 0x2),
    P5_EVENT(P5MMX_SATURATING_MMX_INSTRUCTIONS_EXECUTED, 0x1),
    P5_EVENT(P5MMX_SATURATIONS_PERFORMED, 0x2),
    P5_EVENT(P5MMX_NUMBER_OF_CYCLES_NOT_IN_HALT_STATE, 0x1),
    P5_EVENT(P5MMX_DATA_CACHE_TLB_MISS_STALL_DURATION, 0x2),
    P5_EVENT(P5MMX_MMX_INSTRUCTION_DATA_READS, 0x1),
    P5_EVENT(P5MMX_MMX_INSTRUCTION_DATA_READ_MISSES, 0x2),
    P5_EVENT(P5MMX_FLOATING_POINT_STALLS_DURATION, 0x1),
    P5_EVENT(P5MMX_TAKEN_BRANCHES, 0x2),
    P5_EVENT(P5MMX_D1_STARVATION_AND_FIFO_IS_EMPTY, 0x1),
    P5_EVENT(P5MMX_D1_STARVATION_AND_ONLY_ONE_INSTRUCTION_IN_FIFO, 0x2),
    P5_EVENT(P5MMX_MMX_INSTRUCTION_DATA_WRITES, 0x1),
    P5_EVENT(P5MMX_MMX_INSTRUCTION_DATA_WRITE_MISSES, 0x2),
    P5_EVENT(P5MMX_PIPELINE_FLUSHES_DUE_TO_WRONG_BRANCH_PREDICTIONS, 0x1),
    P5_EVENT(P5MMX_PIPELINE_FLUSHES_DUE_TO_WRONG_BRANCH_PREDICTIONS_RESOLVED_IN_WB_STAGE, 0x2),
    P5_EVENT(P5MMX_MISALIGNED_DATA_MEMORY_REFERENCE_ON_MMX_INSTRUCTIONS, 0x1),
    P5_EVENT(P5MMX_PIPELINE_ISTALL_FOR_MMX_INSTRUCTION_DATA_MEMORY_READS, 0x2),
    P5_EVENT(P5MMX_MISPREDICTED_OR_UNPREDICTED_RETURNS, 0x1),
    P5_EVENT(P5MMX_PREDICTED_RETURNS, 0x2),
    P5_EVENT(P5MMX_MMX_MULTIPLY_UNIT_INTERLOCK, 0x1),
    P5_EVENT(P5MMX_MOVD_MOVQ_STORE_STALL_DUE_TO_PREVIOUS_MMX_OPERATION, 0x2),
    P5_EVENT(P5MMX_RETURNS, 0x1),
    P5_EVENT(P5MMX_BTB_FALSE_ENTRIES, 0x1),
    P5_EVENT(P5MMX_BTB_MISS_PREDICTION_ON_NOT_TAKEN_BRANCH, 0x2),
    P5_EVENT(P5MMX_FULL_WRITE_BUFFER_STALL_DURATION_WHILE_EXECUTING_MMX_INSTRUCTIONS, 0x1),
    P5_EVENT(P5MMX_STALL_ON_MMX_INSTRUCTION_WRITE_TO_E_OR_M_STATE_LINE, 0x2),
};

const struct perfctr_event_set perfctr_p5mmx_event_set = {
    PERFCTR_X86_INTEL_P5MMX,
    &perfctr_p5_event_set,
    ARRAY_SIZE(p5mmx_events), p5mmx_events
};

/*
 * Cyrix 6x86MX, MII, and III events.
 */

static const struct perfctr_event mii_events[] = {
    P5_EVENT(MII_MMX_INSTRUCTIONS_EXECUTED_IN_X_PIPE, 0x1),
    P5_EVENT(MII_MMX_INSTRUCTIONS_EXECUTED_IN_Y_PIPE, 0x2),
    P5_EVENT(MII_EMMS_INSTRUCTIONS_EXECUTED, 0x1),
    P5_EVENT(MII_TRANSITIONS_BETWEEN_MMX_AND_FP_INSTRUCTIONS, 0x2),
    P5_EVENT(MII_SATURATING_MMX_INSTRUCTIONS_EXECUTED, 0x1),
    P5_EVENT(MII_SATURATIONS_PERFORMED, 0x2),
    P5_EVENT(MII_MMX_INSTRUCTION_DATA_READS, 0x1),
    P5_EVENT(MII_TAKEN_BRANCHES, 0x2),
    P5_EVENT(MII_RETURNS_PREDICTED_INCORRECTLY, 0x1),
    P5_EVENT(MII_RETURNS_PREDICTED, 0x2),
    P5_EVENT(MII_MMX_MULTIPLY_UNIT_INTERLOCK, 0x1),
    P5_EVENT(MII_MOVD_MOVQ_STORE_STALL_DUE_TO_PREVIOUS_OPERATION, 0x2),
    P5_EVENT(MII_RETURNS, 0x1),
    P5_EVENT(MII_RSB_OVERFLOWS, 0x2),
    P5_EVENT(MII_BTB_FALSE_ENTRIES, 0x1),
    P5_EVENT(MII_BTB_MISS_PREDICTION_ON_NOT_TAKEN_BRANCH, 0x2),
    P5_EVENT(MII_FULL_WRITE_BUFFER_STALL_DURATION_WHILE_EXECUTING_MMX_INSTRUCTIONS, 0x1),
    P5_EVENT(MII_STALL_ON_MMX_INSTRUCTION_WRITE_TO_E_OR_M_STATE_LINE, 0x2),
    P5_EVENT(MII_L2_TLB_MISSES, 0x3),
    P5_EVENT(MII_L1_TLB_DATA_MISS, 0x3),
    P5_EVENT(MII_L1_TLB_CODE_MISS, 0x3),
    P5_EVENT(MII_L1_TLB_MISS, 0x3),
    P5_EVENT(MII_TLB_FLUSHES, 0x3),
    P5_EVENT(MII_TLB_PAGE_INVALIDATES, 0x3),
    P5_EVENT(MII_TLB_PAGE_INVALIDATES_THAT_HIT, 0x3),
    P5_EVENT(MII_INSTRUCTIONS_DECODED, 0x3),
};

const struct perfctr_event_set perfctr_mii_event_set = {
    PERFCTR_X86_CYRIX_MII,
    &perfctr_p5_event_set,
    ARRAY_SIZE(mii_events), mii_events
};

/*
 * Centaur WinChip C6 events.
 */

static const struct perfctr_event wcc6_events[] = {
    P5_EVENT(WCC6_INTERNAL_CLOCKS, 0x3),
    P5_EVENT(WCC6_VALID_CYCLES_REACHING_WRITEBACKS, 0x3),
    P5_EVENT(WCC6_X86_INSTRUCTIONS, 0x3),
    P5_EVENT(WCC6_DATA_READ_CACHE_MISSES, 0x3),
    P5_EVENT(WCC6_DATA_WRITE_CACHE_MISSES, 0x3),
    P5_EVENT(WCC6_INSTRUCTION_FETCH_CACHE_MISSES, 0x3),
};

const struct perfctr_event_set perfctr_wcc6_event_set = {
    PERFCTR_X86_WINCHIP_C6,
    0,
    ARRAY_SIZE(wcc6_events), wcc6_events
};

/*
 * Centaur WinChip 2 and 3 events.
 */

static const struct perfctr_event wc2_events[] = {
    P5_EVENT(WC2_DATA_READ, 0x3),
    P5_EVENT(WC2_DATA_WRITE, 0x3),
    P5_EVENT(WC2_DATA_TLB_MISS, 0x3),
    P5_EVENT(WC2_DATA_READ_CACHE_MISS, 0x3),
    P5_EVENT(WC2_DATA_WRITE_CACHE_MISS, 0x3),
    P5_EVENT(WC2_DATA_CACHE_WRITEBACKS, 0x3),
    P5_EVENT(WC2_DATA_CACHE_SNOOP_HITS, 0x3),
    P5_EVENT(WC2_PUSH_PUSH_POP_POP_PAIRING, 0x3),
    P5_EVENT(WC2_MISALIGNED_DATA_MEMORY_NOT_IO, 0x3),
    P5_EVENT(WC2_CODE_READ, 0x3),
    P5_EVENT(WC2_CODE_TLB_MISS, 0x3),
    P5_EVENT(WC2_INSTRUCTION_FETCH_CACHE_MISS, 0x3),
    P5_EVENT(WC2_BHT_HITS, 0x3),
    P5_EVENT(WC2_BHT_CANDIDATE, 0x3),
    P5_EVENT(WC2_INSTRUCTIONS_EXECUTED, 0x3),
    P5_EVENT(WC2_INSTRUCTIONS_IN_PIPE_2, 0x3),
    P5_EVENT(WC2_BUS_UTILIZATION, 0x3),
    P5_EVENT(WC2_IO_READ_OR_WRITE_CYCLE, 0x3),
    P5_EVENT(WC2_DATA_READ_OR_DATA_WRITE, 0x3),
    P5_EVENT(WC2_MMX_INSTRUCTIONS_U_PIPE, 0x1),
    P5_EVENT(WC2_MMX_INSTRUCTIONS_V_PIPE, 0x2),
    P5_EVENT(WC2_RETURNS_PREDICTED_INCORRECTLY, 0x1),
    P5_EVENT(WC2_RETURNS_PREDICTED_CORRECTLY, 0x2),
    P5_EVENT(WC2_INTERNAL_CLOCKS, 0x3),
};

const struct perfctr_event_set perfctr_wc2_event_set = {
    PERFCTR_X86_WINCHIP_2,
    0,
    ARRAY_SIZE(wc2_events), wc2_events
};

/*
 * Intel Pentium Pro (P6) events.
 */

#define P6_EVENT(code,mask,qual)	{ #code,code,mask,qual }

static const struct perfctr_event p6_events[] = {
    P6_EVENT(P6_DATA_MEM_REFS, 0x3, 0),
    P6_EVENT(P6_DCU_LINES_IN, 0x3, 0),
    P6_EVENT(P6_DCU_M_LINES_IN, 0x3, 0),
    P6_EVENT(P6_DCU_M_LINES_OUT, 0x3, 0),
    P6_EVENT(P6_DCU_MISS_OUTSTANDING, 0x3, 0),
    P6_EVENT(P6_IFU_FETCH, 0x3, 0),
    P6_EVENT(P6_IFU_FETCH_MISS, 0x3, 0),
    P6_EVENT(P6_ITLB_MISS, 0x3, 0),
    P6_EVENT(P6_IFU_MEM_STALL, 0x3, 0),
    P6_EVENT(P6_ILD_STALL, 0x3, 0),
    P6_EVENT(P6_L2_IFETCH, 0x3, 0xF),
    P6_EVENT(P6_L2_LD, 0x3, 0xF),
    P6_EVENT(P6_L2_ST, 0x3, 0xF),
    P6_EVENT(P6_L2_LINES_IN, 0x3, 0),
    P6_EVENT(P6_L2_LINES_OUT, 0x3, 0),
    P6_EVENT(P6_L2_M_LINES_INM, 0x3, 0),
    P6_EVENT(P6_L2_M_LINES_OUTM, 0x3, 0),
    P6_EVENT(P6_L2_RQSTS, 0x3, 0xF),
    P6_EVENT(P6_L2_ADS, 0x3, 0),
    P6_EVENT(P6_L2_DBUS_BUSY, 0x3, 0),
    P6_EVENT(P6_L2_DBUS_BUSY_RD, 0x3, 0),
    P6_EVENT(P6_BUS_DRDY_CLOCKS, 0x3, 0),
    P6_EVENT(P6_BUS_LOCK_CLOCKS, 0x3, 0),
    P6_EVENT(P6_BUS_REQ_OUTSTANDING, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_BRD, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_RFO, 0x3, 0),
    P6_EVENT(P6_BUS_TRANS_WB, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_IFETCH, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_INVAL, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_PWR, 0x3, 0),
    P6_EVENT(P6_BUS_TRANS_P, 0x3, 0),
    P6_EVENT(P6_BUS_TRANS_IO, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_DEF, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_BURST, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_ANY, 0x3, 0),
    P6_EVENT(P6_BUS_TRAN_MEM, 0x3, 0),
    P6_EVENT(P6_BUS_DATA_RCV, 0x3, 0),
    P6_EVENT(P6_BUS_BNR_DRV, 0x3, 0),
    P6_EVENT(P6_BUS_HIT_DRV, 0x3, 0),
    P6_EVENT(P6_BUS_HITM_DRV, 0x3, 0),
    P6_EVENT(P6_BUS_SNOOP_STALL, 0x3, 0),
    P6_EVENT(P6_FLOPS, 0x1, 0),
    P6_EVENT(P6_FP_COMP_OPS_EXE, 0x1, 0),
    P6_EVENT(P6_FP_ASSIST, 0x2, 0),
    P6_EVENT(P6_MUL, 0x2, 0),
    P6_EVENT(P6_DIV, 0x2, 0),
    P6_EVENT(P6_CYCLES_DIV_BUSY, 0x1, 0),
    P6_EVENT(P6_LD_BLOCKS, 0x3, 0),
    P6_EVENT(P6_SB_DRAINS, 0x3, 0),
    P6_EVENT(P6_MISALIGN_MEM_REF, 0x3, 0),
    P6_EVENT(P6_INST_RETIRED, 0x3, 0),
    P6_EVENT(P6_UOPS_RETIRED, 0x3, 0),
    P6_EVENT(P6_INST_DECODED, 0x3, 0),
    P6_EVENT(P6_HW_INT_RX, 0x3, 0),
    P6_EVENT(P6_CYCLES_INT_MASKED, 0x3, 0),
    P6_EVENT(P6_CYCLES_INT_PENDING_AND_MASKED, 0x3, 0),
    P6_EVENT(P6_BR_INST_RETIRED, 0x3, 0),
    P6_EVENT(P6_BR_MISS_PRED_RETIRED, 0x3, 0),
    P6_EVENT(P6_BR_TAKEN_RETIRED, 0x3, 0),
    P6_EVENT(P6_BR_MISS_PRED_TAKEN_RET, 0x3, 0),
    P6_EVENT(P6_BR_INST_DECODED, 0x3, 0),
    P6_EVENT(P6_BTB_MISSES, 0x3, 0),
    P6_EVENT(P6_BR_BOGUS, 0x3, 0),
    P6_EVENT(P6_BACLEARS, 0x3, 0),
    P6_EVENT(P6_RESOURCE_STALLS, 0x3, 0),
    P6_EVENT(P6_PARTIAL_RAT_STALLS, 0x3, 0),
    P6_EVENT(P6_SEGMENT_REG_LOADS, 0x3, 0),
    P6_EVENT(P6_CPU_CLK_UNHALTED, 0x3, 0),
};

const struct perfctr_event_set perfctr_p6_event_set = {
    PERFCTR_X86_INTEL_P6,
    0,
    ARRAY_SIZE(p6_events), p6_events
};

/*
 * Intel Pentium II events.
 * Note that two PII events (0xB0 and 0xCE) are unavailable in the PIII.
 */

static const struct perfctr_event p2andp3_events[] = {
    P6_EVENT(PII_MMX_SAT_INSTR_EXEC, 0x3, 0),
    P6_EVENT(PII_MMX_UOPS_EXEC, 0x3, 0x0F),
    P6_EVENT(PII_MMX_INSTR_TYPE_EXEC, 0x3, 0x3F),
    P6_EVENT(PII_FP_MMX_TRANS, 0x3, 0),
    P6_EVENT(PII_MMX_ASSIST, 0x3, 0),
    P6_EVENT(PII_SEG_RENAME_STALLS, 0x3, 0x0F),
    P6_EVENT(PII_SEG_REG_RENAMES, 0x3, 0x0F),
    P6_EVENT(PII_RET_SEG_RENAMES, 0x3, 0),
};

static const struct perfctr_event_set p2andp3_event_set = {
    -1,
    &perfctr_p6_event_set,
    ARRAY_SIZE(p2andp3_events), p2andp3_events
};

static const struct perfctr_event pii_events[] = {	/* not in PIII :-( */
    P6_EVENT(PII_MMX_INSTR_EXEC, 0x3, 0),
    P6_EVENT(PII_MMX_INSTR_RET, 0x3, 0),
};

const struct perfctr_event_set perfctr_pii_event_set = {
    PERFCTR_X86_INTEL_PII,
    &p2andp3_event_set,
    ARRAY_SIZE(pii_events), pii_events
};

/*
 * Intel Pentium III events.
 */

static const struct perfctr_event piii_events[] = {
    P6_EVENT(PIII_EMON_KNI_PREF_DISPATCHED, 0x3, 0),
    P6_EVENT(PIII_EMON_KNI_PREF_MISS, 0x3, 0),
    P6_EVENT(PIII_EMON_KNI_INST_RETIRED, 0x3, 0),
    P6_EVENT(PIII_EMON_KNI_COMP_INST_RET, 0x3, 0),
};

const struct perfctr_event_set perfctr_piii_event_set = {
    PERFCTR_X86_INTEL_PIII,
    &p2andp3_event_set,
    ARRAY_SIZE(piii_events), piii_events
};

/*
 * VIA C3 events.
 */

static const struct perfctr_event vc3_events[] = {
    P6_EVENT(VC3_INTERNAL_CLOCKS, 0x2, 0),
    P6_EVENT(VC3_INSTRUCTIONS_EXECUTED, 0x2, 0),
    P6_EVENT(VC3_INSTRUCTIONS_EXECUTED_AND_STRING_ITERATIONS, 0x2, 0),
};

const struct perfctr_event_set perfctr_vc3_event_set = {
    PERFCTR_X86_VIA_C3,
    0,
    ARRAY_SIZE(vc3_events), vc3_events
};

/*
 * AMD K7 events.
 */

#define K7_EVENT(code,qual)	{ #code,code,0xF,qual }

static const struct perfctr_event k7_events[] = {
    K7_EVENT(K7_SEGMENT_REGISTER_LOADS, 0x3F),
    K7_EVENT(K7_STORES_TO_ACTIVE_INSTRUCTION_STREAM, 0),
    K7_EVENT(K7_DATA_CACHE_ACCESSES, 0),
    K7_EVENT(K7_DATA_CACHE_MISSES, 0),
    K7_EVENT(K7_DATA_CACHE_REFILLS_FROM_L2, 0x1F),
    K7_EVENT(K7_DATA_CACHE_REFILLS_FROM_SYSTEM, 0x1F),
    K7_EVENT(K7_DATA_CACHE_WRITEBACKS, 0x1F),
    K7_EVENT(K7_L1_DTLB_MISSES_AND_L2_DTLB_HITS, 0),
    K7_EVENT(K7_L1_AND_L2_DTLB_MISSES, 0),
    K7_EVENT(K7_MISALIGNED_DATA_REFERENCES, 0),
    K7_EVENT(K7_DRAM_SYSTEM_REQUESTS, 0),
    K7_EVENT(K7_SYSTEM_REQUESTS_WITH_THE_SELECTED_TYPE, 0x73),
    K7_EVENT(K7_SNOOP_HITS, 0x7),
    K7_EVENT(K7_SINGLE_BIT_ECC_ERRORS_DETECTED_OR_CORRECTED, 0x3),
    K7_EVENT(K7_INTERNAL_CACHE_LINE_INVALIDATES, 0xF),
    K7_EVENT(K7_CYCLES_PROCESSOR_IS_RUNNING, 0),
    K7_EVENT(K7_L2_REQUESTS, 0xFF),
    K7_EVENT(K7_CYCLES_THAT_AT_LEAST_ONE_FILL_REQUEST_WAITED_TO_USE_THE_L2, 0),
    K7_EVENT(K7_INSTRUCTION_CACHE_FETCHES, 0),
    K7_EVENT(K7_INSTRUCTION_CACHE_MISSES, 0),
    K7_EVENT(K7_INSTRUCTION_CACHE_REFILLS_FROM_L2, 0),
    K7_EVENT(K7_INSTRUCTION_CACHE_REFILLS_FROM_SYSTEM, 0),
    K7_EVENT(K7_L1_ITLB_MISSES, 0),
    K7_EVENT(K7_L2_ITLB_MISSES, 0),
    K7_EVENT(K7_SNOOP_RESYNCS, 0),
    K7_EVENT(K7_INSTRUCTION_FETCH_STALL_CYCLES, 0),
    K7_EVENT(K7_RETURN_STACK_HITS, 0),
    K7_EVENT(K7_RETURN_STACK_OVERFLOW, 0),
    K7_EVENT(K7_RETIRED_INSTRUCTIONS, 0),
    K7_EVENT(K7_RETIRED_OPS, 0),
    K7_EVENT(K7_RETIRED_BRANCHES, 0),
    K7_EVENT(K7_RETIRED_BRANCHES_MISPREDICTED, 0),
    K7_EVENT(K7_RETIRED_TAKEN_BRANCHES, 0),
    K7_EVENT(K7_RETIRED_TAKEN_BRANCHES_MISPREDICTED, 0),
    K7_EVENT(K7_RETIRED_FAR_CONTROL_TRANSFERS, 0),
    K7_EVENT(K7_RETIRED_RESYNC_BRANCHES, 0),
    K7_EVENT(K7_RETIRED_NEAR_RETURNS, 0),
    K7_EVENT(K7_RETIRED_NEAR_RETURNS_MISPREDICTED, 0),
    K7_EVENT(K7_RETIRED_INDIRECT_BRANCHES_WITH_TARGET_MISPREDICTED, 0),
    K7_EVENT(K7_INTERRUPTS_MASKED_CYCLES, 0),
    K7_EVENT(K7_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES, 0),
    K7_EVENT(K7_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS, 0),
    K7_EVENT(K7_INSTRUCTION_DECODER_EMPTY, 0),
    K7_EVENT(K7_DISPATCH_STALLS, 0),
    K7_EVENT(K7_BRANCH_ABORTS_TO_RETIRE, 0),
    K7_EVENT(K7_SERIALIZE, 0),
    K7_EVENT(K7_SEGMENT_LOAD_STALL, 0),
    K7_EVENT(K7_ICU_FULL, 0),
    K7_EVENT(K7_RESERVATION_STATIONS_FULL, 0),
    K7_EVENT(K7_FPU_FULL, 0),
    K7_EVENT(K7_LS_FULL, 0),
    K7_EVENT(K7_ALL_QUIET_STALL, 0),
    K7_EVENT(K7_FAR_TRANSFER_OR_RESYNC_BRANCH_PENDING, 0),
    K7_EVENT(K7_BREAKPOINT_MATCHES_FOR_DR0, 0),
    K7_EVENT(K7_BREAKPOINT_MATCHES_FOR_DR1, 0),
    K7_EVENT(K7_BREAKPOINT_MATCHES_FOR_DR2, 0),
    K7_EVENT(K7_BREAKPOINT_MATCHES_FOR_DR3, 0),
};

const struct perfctr_event_set perfctr_k7_event_set = {
    PERFCTR_X86_AMD_K7,
    0,
    ARRAY_SIZE(k7_events), k7_events
};

/*
 * Helper function to translate a cpu_type code to an event_set pointer.
 */

static const struct perfctr_event_set * const cpu_event_set[] = {
    [PERFCTR_X86_GENERIC] &perfctr_generic_event_set,
    [PERFCTR_X86_INTEL_P5] &perfctr_p5_event_set,
    [PERFCTR_X86_INTEL_P5MMX] &perfctr_p5mmx_event_set,
    [PERFCTR_X86_INTEL_P6] &perfctr_p6_event_set,
    [PERFCTR_X86_INTEL_PII] &perfctr_pii_event_set,
    [PERFCTR_X86_INTEL_PIII] &perfctr_piii_event_set,
    [PERFCTR_X86_CYRIX_MII] &perfctr_mii_event_set,
    [PERFCTR_X86_WINCHIP_C6] &perfctr_wcc6_event_set,
    [PERFCTR_X86_WINCHIP_2] &perfctr_wc2_event_set,
    [PERFCTR_X86_AMD_K7] &perfctr_k7_event_set,
    [PERFCTR_X86_VIA_C3] &perfctr_vc3_event_set,
};

const struct perfctr_event_set *perfctr_cpu_event_set(unsigned cpu_type)
{
    if( cpu_type >= ARRAY_SIZE(cpu_event_set) )
	return 0;
    return cpu_event_set[cpu_type];
}
